home *** CD-ROM | disk | FTP | other *** search
- //
- // "XcShell" Skeletal XCMD/XFCN housekeeping code
- //
- // Copyright ©1991 Mark M. Owen -- All rights reserved
- //
-
- #include <SetupA4.h>
- #include <SegLoad.h>
-
- #include "XCMD.h"
-
-
- extern void UnloadA4Seg (void*aFunctionName);
-
- pascal void main (XCmdBlockPtr paramPtr);
-
-
- pascal void main(XCmdBlockPtr paramPtr)
- {
- Handle hSelf;
-
- // Find out where this code is; lock it so it doesn't move while
- // its in use; set up register A4 for access to our "world"
-
- RememberA0();
- SetUpA4();
- asm {
- _RecoverHandle;
- move.l A0,hSelf;
- }
- HLock( hSelf);
-
- {
- register
- hGlobals **hG, hGlb;
-
- // try to find an existing GLOBALTYPE resource named GLOBALS in the
- // current resource file.
-
- ResrvMem( sizeof(Handle) );
- if( !(hG = (hGlobals**)Get1NamedResource( GLOBALTYPE, GLOBALS )) ) {
- int resId;
-
- // create a GLOBALSTYPE resource in which we will keep a
- // reference to a relocatable chunk of memory in which the
- // values of our globals will be kept between calls. note
- // that the resource contains a handle to the actual globals
- // record in memory, written to disk (initially zero) so it
- // can be located easily when needed.
-
- **( hG = (hGlobals**)NewHandle( sizeof(Handle) ) ) = 0L;
- do resId = UniqueID( GLOBALTYPE );
- while( resId < 128 );
- AddResource( (Handle)hG, GLOBALTYPE, resId, GLOBALS );
- WriteResource( (Handle)hG );
- UpdateResFile( CurResFile() );
- }
-
- HLock( (Handle)hG ); // lock the global resource record
-
- if( !(hGlb = **hG) ) {
- long grow=5;
-
- MaxApplZone(); // expand the callers heap zone if possible
-
- while( grow-- )
- MoreMasters(); // allocate a few master pointer blocks
-
- grow = MaxMem( &grow );
-
- // allocate the relocatable space in which we will keep
- // the values of our globals will be kept between calls
- // and write the address out to disk so we can find it
- // next time we are called. initial value is all zeros.
-
- ResrvMem( sizeof( globals ) );
- hGlb = (hGlobals)NewHandleClear( sizeof(globals) );
- HLock( (Handle)hGlb );
- **hG = hGlb;
- WriteResource( (Handle)hG );
- UpdateResFile( CurResFile() );
-
- // load the related XCMD resources in to memory and
- // record their handles in our globals. while we are
- // at it, we'll put them in high memory and lock them.
-
- (**hGlb).hVerbs = Get1NamedResource( 'STR#', VERBS );
- (**hGlb).hNParams = Get1NamedResource( 'vprm', NPARAMS );
- (**hGlb).nVerbs = *((int*)(*((**hGlb).hVerbs)));
-
- MoveHHi( (**hGlb).hVerbs );
- HLock( (**hGlb).hVerbs );
- MoveHHi( (**hGlb).hNParams );
- HLock( (**hGlb).hNParams );
- }
-
- RestoreGlobals( *hGlb ); // load global values saved after the last call
-
- // run the XCMD code
-
- if( XCMD( paramPtr, hGlb ) == DEAD ) {
-
- // dispose requested: time to terminate
-
- HUnlock( (**hGlb).hVerbs );
- ReleaseResource( (**hGlb).hVerbs );
- HUnlock( (**hGlb).hNParams );
- ReleaseResource( (**hGlb).hNParams );
- HUnlock( (Handle)hGlb );
- DisposHandle( (Handle)hGlb );
- **hG = 0L;
- WriteResource( (Handle)hG );
- UpdateResFile( CurResFile() );
- ReleaseResource( (Handle)hG );
- UnloadA4Seg( 0L );
- }
- else
- SaveGlobals( *hGlb ); // store global values for use during the next call
-
- HUnlock( (Handle)hG ); // allow the globals to float around
- }
-
- // make ourselves relocatable again and restore register A4's contents
-
- HUnlock( hSelf );
- RestoreA4();
- }